package com.gz.EuchreU.Scene;

import javax.microedition.khronos.opengles.GL10;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.opengl.util.GLHelper;

import android.util.Log;

import com.badlogic.gdx.math.Vector2;
import com.gz.EuchreU.Contants.CardLocations;
import com.gz.EuchreU.Contants.CardValues;
import com.gz.EuchreU.Contants.GameOptions;
import com.gz.EuchreU.Contants.GameState;
import com.gz.EuchreU.Contants.Suits;
import com.gz.EuchreU.Contants.UI;
import com.gz.EuchreU.Controls.CallSuitMenu;
import com.gz.EuchreU.Controls.InGameSplash;
import com.gz.EuchreU.Controls.OrderUpMenu;
import com.gz.EuchreU.Controls.ScoreBoardMenu;
import com.gz.EuchreU.Helpers.Textures;
import com.gz.EuchreU.Sprite.Card;
import com.gz.Game.Extension.GameScene;

public class EuchreGameScene extends GameScene{

	public static final int LAYER_TABLE = 0;
	public static final int LAYER_CARDS = LAYER_TABLE + 1;
	public static final int LAYER_HUD = LAYER_CARDS + 1;
	
	private static final float IDLE_LOG_TIME = 20;
	
	private boolean mLoaded = false;
	private float mIdleTimeLeft = 0;
	private float mIdleLogTime = 0;
	private float mWinnerIdleTime = GameOptions.GetIntOption(GameOptions.PREF_INT_PAUSE_LENGTH) * 2;
	private CallSuitMenu mCallMenu;
	private OrderUpMenu mOrderMenu;
	private ScoreBoardMenu mScoreBoard;
	private AnimatedSprite mSuits;
	private Sprite mDealerChip;
	private Sprite mCalledChip;
	private Sprite mCurrentPlayer;
	private InGameSplash mSplash;
	
	public EuchreGameScene(int pLayerCount, Engine baseEngine) {
		super(pLayerCount, baseEngine);
		
		GameState.ResetAll();
		
		registerUpdateHandler(getUpdateHandler());
		setOnSceneTouchListener(getTouchListener());
		setOnAreaTouchTraversalFrontToBack();
		
		setBackground(new ColorBackground(0f, .3f, .04f));
		
	}

	@Override
	protected void onLoadComplete() {
		log("Load complete");
	}

	@Override
	protected void onLoadResources() {
		log("Load Resources");
	}

	@Override
	protected void onLoadScene() {
		log("Load scene");
		InitGame();
	}

	@Override
	protected void unloadScene() {

	}

	@Override
	protected void onManagedDraw(final GL10 pGL, final Camera pCamera) {
		try {
			
				super.onManagedDraw(pGL, pCamera);
			
		} catch (Exception e) {
			Log.e("EuchreGameScene", e.getMessage());
		}
	}
	
	private void InitGame(){
		InitCards();
		InitHuds();
	}
	
	private void InitCards(){
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 6; j++) {
				Card card = new Card(20,20,i,j);
				GameState.AddCard(card);
				this.getChild(LAYER_CARDS).attachChild(card);
			}
		}
	}
	
	private void InitHuds(){
		mOrderMenu = new OrderUpMenu(UI.getWidth()/6, UI.getHeight()/3, 5*UI.getWidth()/6f, this);
		mCallMenu = new CallSuitMenu(UI.getWidth()/6, UI.getHeight()/4, 2*UI.getWidth()/3f, this);
		mScoreBoard = new ScoreBoardMenu(UI.getWidth()/5, UI.getHeight()/3, UI.getWidth()/2, this);
		mSuits = new AnimatedSprite(10,10,UI.getCardWidth(),UI.getCardWidth(), UI.getTextures().getTiledSuits());

		mSuits.setCurrentTileIndex(4);
		
		mDealerChip = new Sprite(UI.getWidth(),0,UI.getCardWidth()/2,UI.getCardWidth()/2,UI.getTextures().getTexture(Textures.DEALER_TEXTURE));
		mCalledChip = new Sprite(UI.getWidth(),0,UI.getCardWidth()/2,UI.getCardWidth()/2,UI.getTextures().getTexture(Textures.ORDERED_BUTTON));
		mCurrentPlayer = new Sprite(UI.getWidth(),0,UI.getCardWidth(),UI.getCardWidth(),UI.getTextures().getTexture(Textures.GREEN_GLASS_TEXTURE));
		
		mSplash = new InGameSplash();
		mSplash.Show();
		this.getChild(LAYER_HUD).attachChild(mOrderMenu);
		this.getChild(LAYER_HUD).attachChild(mCallMenu);
		this.getChild(LAYER_HUD).attachChild(mScoreBoard);
		this.getChild(LAYER_HUD).attachChild(mSuits);
		this.getChild(LAYER_TABLE).attachChild(mDealerChip);
		this.getChild(LAYER_TABLE).attachChild(mCalledChip);
		this.getChild(LAYER_TABLE).attachChild(mCurrentPlayer);
		this.getChild(LAYER_HUD).attachChild(mSplash);
	}
	
	private IUpdateHandler getUpdateHandler(){
		return new IUpdateHandler(){

			public void onUpdate(float pSecondsElapsed) {
				if(!mLoaded){
					mLoaded = true;
					InitGame();
					GameState.InitPlayers();
					GameState.Shuffle();
					mSplash.Hide();
				}
				else{
					
					if(mIdleLogTime >= IDLE_LOG_TIME){
						mIdleLogTime = 0;
						GameState.LogState("Idle State Update");
					}
					else{
						mIdleLogTime += pSecondsElapsed;
					}
					
					UpdateHuds();
					
					switch (GameState.getGameState()) {
					case GameState.SHUFFLING:
						UpdateShuffle();
						break;
					case GameState.DEALING:
						UpdateDealing(pSecondsElapsed);
						break;
					case GameState.TRUMP_CALLED:
						UpdateTrumpCalled(pSecondsElapsed);
						break;
					case GameState.SHOW_WINNER:
						UpdateShowWinner(pSecondsElapsed);
						break;
					case GameState.PLAYING_TRICKS:
					case GameState.TURN_CARD_DOWN:
					case GameState.TURN_CARD_UP:
					case GameState.DISCARDING:
						GameState.GetPlayers()[GameState.getCurrentPlayer()].Update(pSecondsElapsed);
						break;
					default:
						break;
					}
				}
			}

			public void reset() {
				
			}

			private void UpdateHuds(){
				
				if(GameState.getGameState() != GameState.TURN_CARD_UP){
					mOrderMenu.Hide();
				}
				else mOrderMenu.Show();
				
				if(GameState.getGameState() != GameState.TURN_CARD_DOWN){
					mCallMenu.Hide();
				}
				else mCallMenu.Show();
				
				if(mSuits.getCurrentTileIndex() != Suits.getTrumpID()){
					log("Current suit: " + Suits.getTrumpID());
					mSuits.setCurrentTileIndex(Suits.getTrumpID());
				}
				
				
				mDealerChip.setPosition(CardLocations.GetDealerChipLocation().x, CardLocations.GetDealerChipLocation().y);
				mCalledChip.setPosition(CardLocations.GetCalledChipLocation().x, CardLocations.GetCalledChipLocation().y);
				mCurrentPlayer.setPosition(CardLocations.GetTrickCardLocation(GameState.getCurrentPlayer()).x,CardLocations.GetTrickCardLocation(GameState.getCurrentPlayer()).y);
				
				mCallMenu.Update();
				mScoreBoard.Update();
			}
			
			private void UpdateShuffle(){
				boolean wait = false;
				for(Card card:GameState.GetCards()){
					if(card.IsMoving()){
						wait = true;
					}
				}
				
				
				if(wait == false)GameState.setState(GameState.DEALING);
			}
			
			private void UpdateDealing(float pSecondsElapsed){
				if(mIdleTimeLeft <= 0){
					mIdleTimeLeft = GameState.getDealIdleTime();
					if(GameState.GetDealingIndex() <20)
					{
						//Player cards
						int currentPlayer = GameState.getCurrentPlayer();
						Card currentCard = GameState.GetCards().get(GameState.GetShuffledIndecies()[GameState.GetDealingIndex()]);
						GameState.GetPlayers()[currentPlayer].AddCard(currentCard);
						
						GameState.AddToDealingIndex();
						switch (GameState.GetDealingIndex()){
						case 3:
						case 5:
						case 8:
						case 10:
						case 12:
						case 15:
						case 17:
						case 20:
							GameState.DealNextPlayer();
							mIdleTimeLeft *= 1.5f;
							break;
						default:
								break;
						}
					}
					else if(GameState.GetDealingIndex() == 20)
					{
						GameState.GetCards().get(GameState.GetShuffledIndecies()[GameState.GetDealingIndex()]).setState(Card.STATE_TURNCARD);
						GameState.SetTurnCard(GameState.GetCards().get(GameState.GetShuffledIndecies()[GameState.GetDealingIndex()]));
						GameState.GetCards().get(GameState.GetShuffledIndecies()[GameState.GetDealingIndex()]).MoveTo(new Vector2(UI.getWidth()/2 - UI.getCardWidth()/2, UI.getHeight()/2 - UI.getCardWidth()/2));
						GameState.AddToDealingIndex();
					}
					else if(GameState.GetDealingIndex() < GameState.GetCards().size()){
						GameState.GetCards().get(GameState.GetShuffledIndecies()[GameState.GetDealingIndex()]).setState(Card.STATE_DISCARDED);
						GameState.GetCards().get(GameState.GetShuffledIndecies()[GameState.GetDealingIndex()]).MoveTo(new Vector2(UI.getWidth()/2 - UI.getCardWidth()/2, UI.getHeight()/2 - UI.getCardWidth()/2),false,false);
						int kitIndex = GameState.GetCards().size() - GameState.GetDealingIndex() - 1;
						log("Kitty index: " + kitIndex);
						GameState.setKitty(GameState.GetCards().get(GameState.GetShuffledIndecies()[GameState.GetDealingIndex()]), kitIndex);
						GameState.AddToDealingIndex();
					}
					else{
						GameState.ResetDealingIndex();
						GameState.setState(GameState.TURN_CARD_UP);
					}
				}
				else{
					mIdleTimeLeft -= pSecondsElapsed;
				}
			}
			
			private void UpdateTrumpCalled(float pSecondsElapsed){
				GameState.StartPlayingTricks();
			}
			
			private void UpdateShowWinner(float pSecondsElapsed){
				if(mWinnerIdleTime <= 0){
					mWinnerIdleTime = GameOptions.GetIntOption(GameOptions.PREF_INT_PAUSE_LENGTH) * 2;
				}
				else{
					mWinnerIdleTime -= pSecondsElapsed;
				}
			}
			
		};
	}
	
	private IOnSceneTouchListener getTouchListener(){
		return new IOnSceneTouchListener() {

			public boolean onSceneTouchEvent(Scene pScene,
					TouchEvent pSceneTouchEvent) {
				if(CardValues.IsCardTouched()){
					log("Card is touched");
					for(Card card:GameState.GetCards()){
						if(CardValues.getCurrentCard() == card.getCardID()){
							card.onCardTouched(pSceneTouchEvent);
							return true;
						}
					}
				}
				else if(UI.IsScoreBoardTouched()){
					log("ScoreBoard is touched");
					mScoreBoard.OnTouch(pSceneTouchEvent);
				}
				else
				{
					log("Unhandled touch event");
					//TODO: Possibly camera work here?
					
					if(GameState.getGameState() == GameState.SHOW_WINNER || GameState.getGameState() == GameState.INITIALIZING){
						GameState.Shuffle();
					}
				}
				
				return true;
			}
			
		};
	}
	
	private void log(String msg){
		Log.d("Euchre Game Scene", msg);
		mIdleLogTime = 0;
	}
	
}
